<?php

/**
 * 桥接模式: 将抽象和实现解耦，让它们可以独立变化. 一个类存在两个（或多个）独立变化的维度，通过组合的方式可以让这两个（或多个）维度可以独立进行扩展.
 * 桥接模式 主要针对 二维模型. 常规方法需要A*B种类,而桥接模式只需要A+B种类，维度越多，各维度下的分类越多，桥接模式越有优势.
 */


/**
 * 抽象的信息类
 */
abstract class Msg {
    public $bridge;

    public function __construct(MessageType $bridge) {
        $this->bridge = $bridge;
    }

    abstract public function msg($content);

    public function send($to, $content) {
        $content = $this->msg($content);
        $this->bridge->send($to, $content);
    }
}

/**
 * 按照 紧急程度 划分三个类
 */
//严重程度
class Severe extends Msg {
    public function msg($content) {
        return '[严重] ' . $content;
    }
}

//紧急程度
class Urgency extends Msg {
    public function msg($content) {
        return '[紧急] ' . $content;
    }
}

//普通程度
class Normal extends Msg {
    public function msg($content) {
        return '[普通] ' . $content;
    }
}

/**
 * 按照 告警类型 划分三个类
 */
interface MessageType {
    function send($to, $content);
}

//发送邮件
class Email implements MessageType {
    public function send($user, $content) {
        echo "[发邮件] 给{$user}: {$content}" . PHP_EOL;
    }
}

//发送微信
class Weixin implements MessageType {
    public function send($user, $content) {
        echo "[发微信消息] 给{$user}: {$content}" . PHP_EOL;
    }
}

//打电话
class Phone implements MessageType {
    public function send($user, $content) {
        echo "[打语音电话] 给{$user}: {$content}" . PHP_EOL;
    }
}

//根据业务需求, 客户端任意组合调用
//严重程度发邮件
$client = new Severe(new Email());
$client->send('张三', '服务器异常了1'); //[发邮件] 给张三: [严重] 服务器异常了1

//严重程度发微信消息
$client = new Severe(new Weixin());
$client->send('张四', '服务器异常了2'); //[发微信消息] 给张四: [严重] 服务器异常了2

//严重程度打语音电话
$client = new Severe(new Phone());
$client->send('张五', '服务器异常了3'); //[打语音电话] 给张五: [严重] 服务器异常了3

//紧急程度发邮件
$client = new Urgency(new Email());
$client->send('李三', '刚才接口响应超时了1'); //[发邮件] 给李三: [紧急] 刚才接口响应超时了1

//紧急程度发微信消息
$client = new Urgency(new Weixin());
$client->send('李四', '刚才接口响应超时了2'); //[发微信消息] 给李四: [紧急] 刚才接口响应超时了2

//紧急程度打语音电话
$client = new Urgency(new Phone());
$client->send('李五', '刚才接口响应超时了3'); //[打语音电话] 给李五: [紧急] 刚才接口响应超时了3

//普通程度发邮件
$client = new Normal(new Email());
$client->send('王三', '记得下班打卡1'); //[发邮件] 给王三: [普通] 记得下班打卡1

//普通程度发微信消息
$client = new Normal(new Weixin());
$client->send('王四', '记得下班打卡2'); //[发微信消息] 给王四: [普通] 记得下班打卡2

//普通程度打语音电话
$client = new Normal(new Phone());
$client->send('王五', '记得下班打卡3'); //[打语音电话] 给王五: [普通] 记得下班打卡3


//如下为传统方式, 实现起来有很多冗余的代码和逻辑
function SevereEmail($user, $content) {
    echo "[发邮件] 给{$user}: [严重] {$content}";
}

function SevereWeixin($user, $content) {
    echo "[发微信消息] 给{$user}: [严重] {$content}";
}

function SeverePhone($user, $content) {
    echo "[打语音电话] 给{$user}: [严重] {$content}";
}

function UrgencyEmail($user, $content) {
    echo "[发邮件] 给{$user}: [紧急] {$content}";
}

function UrgencyWeixin($user, $content) {
    echo "[发微信消息] 给{$user}: [紧急] {$content}";
}

function UrgencyPhone($user, $content) {
    echo "[打语音电话] 给{$user}: [紧急] {$content}";
}

function NormalEmail($user, $content) {
    echo "[发邮件] 给{$user}: [普通] {$content}";
}

function NormalWeixin($user, $content) {
    echo "[发微信消息] 给{$user}: [普通] {$content}";
}

function NormalPhone($user, $content) {
    echo "[打语音电话] 给{$user}: [普通] {$content}";
}